// 根据 a.b.c 去获取对象中的值
const getValueByExp = <T extends object>(data: T, exp: string): any | T => {
  // const getValueByExp = <T extends Object, K extends keyof T>( data: T, exp: K): T[K] | T => {

  // TODO
  let ret: any = data;

  if (typeof exp === "string") {
    const keys = exp.split(".");
    let result = JSON.parse(JSON.stringify(data));
    keys.forEach(item => (result = result[item]));
    ret = result;
  }

  return ret;
};

// canvas 将图片地址转换为 base64
const canvasToBase64 = (imgSrc: string): Promise<string> => {
  return new Promise(resolve => {
    const img = document.createElement("img");
    // 图片跨域问题
    img.setAttribute("crossOrigin", "Anonymous");
    img.src = imgSrc;

    img.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx: CanvasRenderingContext2D | null = canvas.getContext("2d");
      if (ctx) {
        ctx.drawImage(img, 0, 0, img.width, img.height);
        const dataURL = canvas.toDataURL("image/png");
        resolve(dataURL);
      } else {
        resolve("没有获取到 canvas 上下文对象");
      }
    };
    img.onerror = e => {
      resolve(e.toString());
    };
  });
};

// fileReader 读取 Blob, 支持类型: ArrayBuffer | Binary | Base64 | Text
const fileReaderFile = (
  file: Blob,
  type: "ArrayBuffer" | "Binary" | "Base64" | "Text" = "Base64"
): Promise<string | ArrayBuffer | void> => {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    switch (type) {
      case "ArrayBuffer":
        fileReader.readAsArrayBuffer(file);
        break;
      case "Binary":
        fileReader.readAsBinaryString(file);
        break;
      case "Base64":
        fileReader.readAsDataURL(file);
        break;
      case "Text":
        fileReader.readAsText(file);
        break;
      default:
        console.error("未知的读取类型: ", type);
        break;
    }

    fileReader.onload = () => {
      if (fileReader.readyState === FileReader.DONE && fileReader.result) {
        resolve(fileReader.result);
      }
    };
    fileReader.onerror = () => {
      reject(fileReader.error);
    };
  });
};

// 解析excel成 json
// import * as XLSX from "xlsx";
// const parseExcelToJson = (file: Blob) => {
//   return new Promise(async (resolve, reject) => {
//     const binaryData = await fileReaderFile(file, "Binary");
//     // 解析成二进制格式数据
//     const workbook = XLSX.read(binaryData, { type: "binary" });

//     const SheetNames = workbook.SheetNames;
//     const len = SheetNames.length;

//     const workData: Record<string, any> = {
//       json: {}, // json 数据
//       workbook, // 工作表
//     };

//     for (let i = 0; i < len; i++) {
//       // 工作表名
//       const sheetName = SheetNames[i];
//       // 工作表
//       const worksheet = workbook.Sheets[sheetName];
//       // 转换为 json
//       const json = XLSX.utils.sheet_to_json(worksheet);

//       workData.json[sheetName] = json;
//     }
//     resolve(workData);
//   });
// };

// 获取 css 样式
const getCssStyle = (dom: HTMLElement, property: string, defaultValue?: any) => {
  const cssDescript = window.getComputedStyle(dom);
  return cssDescript.getPropertyValue(property) || defaultValue;
};

// 获取DOM的宽高
const getDomWH = (el: HTMLElement) => {
  let result = {
    width: 0,
    height: 0
  };
  const width = getCssStyle(el, "width", 0);
  const height = getCssStyle(el, "height", 0);
  result = {
    width: parseFloat(width),
    height: parseFloat(height)
  };
  return result;
};

// path1 到 path2 的相对路径
const relativePath = (path1: string, path2: string) => {
  let str = "";
  const p1 = path1.split("/"); //split("字符串或正则表达式",length数组最多个数)
  const p2 = path2.split("/");
  for (let i = 1; i < p2.length; i++) {
    if (p1[i] === p2[i]) {
      str = str + "../";
    } else {
      str = str + p2[i] + "/";
    }
  }
  return str.substr(0, str.length - 1); //处理末尾多的 /
};

// 数字转大写
const numTransitionBig = (n: number | string): string => {
  if (typeof n === "number") {
    n = n.toString();
  }
  if (Number(n) < 0) {
    return "零";
  }

  // if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) {
  //   return "数据非法";  //判断数据是否大于0
  // }

  let unit = "千百拾亿千百拾万千百拾元角分";
  let str = "";

  n += "00";

  // 是否是小数
  const indexpoint = n.indexOf(".");

  // 小数, 截取需要使用的unit单位
  if (indexpoint >= 0) {
    n = n.substring(0, indexpoint) + n.substr(indexpoint + 1, 2);
  }

  // 整数, 截取需要使用的unit单位
  unit = unit.substr(unit.length - n.length);
  for (let i = 0; i < n.length; i++) {
    str += "零壹贰叁肆伍陆柒捌玖".charAt(Number(n.charAt(i))) + unit.charAt(i);
  }

  // 替换掉数字里面的零字符
  return str
    .replace(/零(千|百|拾|角)/g, "零")
    .replace(/(零)+/g, "零")
    .replace(/零(万|亿|元)/g, "$1")
    .replace(/(亿)万|壹(拾)/g, "$1$2")
    .replace(/^元零?|零分/g, "")
    .replace(/元$/g, "元整");
};

// 将 xxx_yyy-zzz 转换为 xxxYyyZzz
const camelize = (str: string, symbol = "[_|-]"): string => {
  const reg = new RegExp(`${symbol}(\\w)`, "g");
  return str.replace(reg, (_, c) => (typeof c === "string" ? c.toUpperCase() : ""));
};

// 将 xxxYyyZzz 转换为 xxx_yyy_zzz 或者 xxx-yyy-zzz
const snakeCase = (str: string, symbol = "_"): string => {
  const reg = new RegExp(`([A-Z])`, "g");
  return str.replace(reg, (_, c) => (typeof c === "string" ? symbol + c.toLowerCase() : ""));
};

export {
  getValueByExp,
  canvasToBase64,
  fileReaderFile,
  getCssStyle,
  getDomWH,
  relativePath,
  numTransitionBig,
  camelize,
  snakeCase
};
